from django_redis import get_redis_connection
import base64
import pickle


def merge_cart_cookie_to_redis(request, user, response):
    """登录后，合并cookie数据到redis中
    我们需要在普通登录，和ＱＱ登录中补充逻辑"""
    # 1.获取cookie中的数据
    cookie_cart = request.COOKIES.get('cart')
    # 2.cookie中没有数据，返回，不进行合并
    if not cookie_cart:
        return response
    # 3.进行解析
    cookie_cart = pickle.loads(base64.b64decode(cookie_cart.encode()))
    # 3.1取出redis中的数据进行重新构造，主要是针对同一商品以cookie为准
    redis_conn = get_redis_connection('cart')
    redis_cart = redis_conn.hgetall('cart_%s' % user.id)
    redis_selected = redis_conn.smembers('cart_selected_%s' % user.id)
    # 保存redis中的勾选状态到变量中之后进行删除redis集合中的数据,
    # redis_cart = {
    #     商品sku_id  bytes字节类型:  商品数量  bytes字节类型
    #     商品sku_id  bytes字节类型:  商品数量  bytes字节类型
    # ...}
    if redis_selected:
        redis_conn.srem('cart_selected_%s' % user.id, *redis_selected)
    # 现在所有的内容就都在redis_selected这个变量中保存了，操作这个集合就可以了，当然了，它是bytes类型的
    cart = {}
    for sku_id, count in redis_cart.items():
        # redis中获取到的是bytes类型，要先进行转换
        cart[int(sku_id)] = int(count)

    for sku_id, count_selected in cookie_cart.items():
        # 在字典类型中，原先有值会覆盖，没有值会新增
        cart[sku_id] = count_selected['count']
        # 处理勾选状态
        selected = count_selected['selected']
        # 要转成bytes类型再进行添加(数字不能decode,需要先转成字符串)
        sku_id = str(sku_id).encode()
        # print(sku_id)
        if selected:
            # 表示在cookie中是勾选的状态，加到集合中,
            redis_selected.add(sku_id)
        else:
            redis_selected.remove(sku_id)
    # 执行redis数据库的保存
    pl = redis_conn.pipeline()
    pl.hmset('cart_%s' % user.id, cart)
    pl.sadd('cart_selected_%s' % user.id, *redis_selected)
    pl.execute()

    # 4.删除cookie中的数据
    response.delete_cookie('cart')
    return response
